package com.crazy.cloud.user.biz.service.impl;

import com.crazy.cloud.common.exception.DataConflictException;
import com.crazy.cloud.common.utils.ConvertUtils;
import com.crazy.cloud.common.utils.PasswordUtil;
import com.crazy.cloud.common.utils.SaltUtil;
import com.crazy.cloud.user.api.constant.UserStatusEnum;
import com.crazy.cloud.user.api.dto.UserDTO;
import com.crazy.cloud.user.api.dto.UserRegisterDTO;
import com.crazy.cloud.user.api.service.UserService;
import com.crazy.cloud.user.biz.utils.GuidUtil;
import com.crazy.cloud.user.biz.utils.GuidUtil.GuidBizTypeEnum;
import com.crazy.cloud.user.domain.model.User;
import com.crazy.cloud.user.domain.model.UserLogin;
import com.crazy.cloud.user.domain.repository.UserLoginRepository;
import com.crazy.cloud.user.domain.repository.UserRepository;
import java.math.BigDecimal;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @program: crazy-cloud
 * @description: 用户service实现
 * @author: CrazyMan
 * @create: 2018/9/26 下午2:31
 **/
@Slf4j
@RestController
@RequestMapping("/users")
public class UserServiceImpl implements UserService {

    @Autowired
    UserRepository userRepository;
    @Autowired
    UserLoginRepository userLoginRepository;

    /**
     * 根据clientId查询
     *
     * @param clientId 用户唯一ID
     */
    @Override
    @GetMapping("/{clientId}")
    public UserDTO getUserInfoByClientId(@PathVariable String clientId) {
        UserDTO userDTO = ConvertUtils.convert(userRepository.selectByEntityId(clientId), UserDTO.class);
        return userDTOBuilder(userDTO);
    }

    /**
     * 根据电话查询
     *
     * @param phoneNo 电话号码
     */
    @Override
    @GetMapping("/phone/{phoneNo}")
    public UserDTO getUserInfoByPhoneNo(@PathVariable String phoneNo) {
        return userDTOBuilder(ConvertUtils.convert(userRepository.selectUserByPhoneNo(phoneNo), UserDTO.class));
    }

    /**
     * 根据邮箱查询
     *
     * @param email 邮箱
     */
    @Override
    @GetMapping("/email")
    public UserDTO getUserInfoByEmail(@RequestParam String email) {
        return userDTOBuilder(ConvertUtils.convert(userRepository.selectUserByEmail(email), UserDTO.class));
    }

    /**
     * 用户名查询
     *
     * @param username 用户名
     */
    @Override
    @GetMapping("/username/{username}")
    public UserDTO getUserInfoByUsername(@PathVariable String username) {
        return userDTOBuilder(ConvertUtils.convert(userRepository.selectUserByUsername(username), UserDTO.class));
    }

    @Override
    @PostMapping
    @Transactional(rollbackFor = Exception.class)
    public String userRegister(@RequestBody UserRegisterDTO userRegisterDTO) throws DataConflictException {
        User user = userBuilder(userRegisterDTO);
        //保存基本用户信息
        userRepository.insert(user);
        //保存密码信息
        userLoginRepository.insert(userLoginBuilder(user.getClientId(), userRegisterDTO.getPassword()));
        return user.getClientId();
    }


    private UserDTO userDTOBuilder(UserDTO userDTO) {
        if (null != userDTO) {
            UserLogin userLogin = userLoginRepository.selectByEntityId(userDTO.getClientId());
            if (null != userLogin) {
                userDTO.setPassword(userLogin.getPasswordEncryption());
                userDTO.setSalt(userLogin.getSalt());
            }

        }
        return userDTO;
    }

    private User userBuilder(UserRegisterDTO userRegisterDTO) {
        User user = User.builder()
            .clientId(GuidUtil.nextId(GuidBizTypeEnum.CLIENT_ID))
            .actived(BigDecimal.ONE.intValue())
            .email(userRegisterDTO.getEmail())
            .username(userRegisterDTO.getUsername())
            .phoneNo(userRegisterDTO.getPhoneNo())
            .build();
        user.setCreator(user.getClientId());
        user.setModifier(user.getCreator());
        return user;
    }

    private UserLogin userLoginBuilder(String clientId, String password) {
        UserLogin userLogin = UserLogin.builder()
            .clientId(clientId)
            .salt(SaltUtil.getSalt())
            .status(UserStatusEnum.APPROVED.getValue())
            .build();
        userLogin.setPasswordEncryption(PasswordUtil.encryptSha256(password, userLogin.getSalt()));
        userLogin.setCreator(clientId);
        userLogin.setModifier(clientId);
        return userLogin;
    }
}
